 /*
 Copyright (C) 2024 HiHope Open Source Organization .
 Licensed under the Apache License, Version 2.0 (the "License");
 you may not use this file except in compliance with the License.
 You may obtain a copy of the License at

     http://www.apache.org/licenses/LICENSE-2.0

 Unless required by applicable law or agreed to in writing, software
 distributed under the License is distributed on an "AS IS" BASIS,
 WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 See the License for the specific language governing permissions and
 limitations under the License.
 */

#include <stdio.h>
#include <stdlib.h>
#include <string.h>

#include "ohos_init.h"
#include "cmsis_os2.h"

#include "MQTTClient.h"     // MQTTClient-C库接口文件
#include "mqtt_ohos.h"      // OHOS适配接口文件

#include "wifi_sta.h"
#include "mqtt_task.h"

#include "iot_gpio.h"
#include "iot_gpio_ex.h"

#ifdef SUPPORT_AHT20
#include "iot_i2c.h"
#include "iot_errno.h"
#include "aht20.h"
#endif

#define SSID    "HDC_2025"   // AP名称
#define PSWD    "12345678"   // AP密码

#ifdef SUPPORT_AHT20
#define I2C_BAUDRATE      (400000)
#define I2C_IDX           (1)
unsigned int g_i2c_init = IOT_FAILURE;
#endif

extern int door;
void HwGpioInit(void)
{
    IoTGpioInit(1);

    IoTGpioSetDir(LIGHT_ON_OFF_CTRL_GPIO, IOT_GPIO_DIR_OUT);
    IoTGpioSetDir(FAN_ON_OFF_CTRL_GPIO, IOT_GPIO_DIR_OUT);
    IoTGpioSetDir(DOOR_ON_OFF_CTRL_GPIO, IOT_GPIO_DIR_OUT);
    IoTGpioSetDir(BEEP_ON_OFF_CTRL_GPIO, IOT_GPIO_DIR_OUT);
    IoTGpioSetOutputVal(LIGHT_ON_OFF_CTRL_GPIO, 0);
    IoTGpioSetOutputVal(FAN_ON_OFF_CTRL_GPIO, 0);
    IoTGpioSetOutputVal(DOOR_ON_OFF_CTRL_GPIO, 0);
    IoTGpioSetOutputVal(BEEP_ON_OFF_CTRL_GPIO, 0);

#ifdef SUPPORT_AHT20
    // 设置GPIO-15/16引脚功能为I2C1_SDA/I2C1_SCL，并初始化I2C1
    IoSetFunc(IOT_IO_NAME_GPIO_15, IOT_IO_FUNC_GPIO_15_I2C1_SDA);
    IoSetFunc(IOT_IO_NAME_GPIO_16, IOT_IO_FUNC_GPIO_16_I2C1_SCL);
    g_i2c_init = IoTI2cInit(I2C_IDX, I2C_BAUDRATE);
#endif
}

static void MainTask(void *arg)
{
    (void)arg;
    int rc = -1;
    char payload[PAYLOAD_BUFF_LEN] = {0};
    uint8_t i = 0;
    float temp = 20.12345f;
    float humi = 60.56789f;

    HwGpioInit();

#ifdef SUPPORT_AHT20
    if (g_i2c_init == IOT_SUCCESS) {
        while (IOT_SUCCESS != AHT20_Calibrate()) {
            printf("[main_task] MainTask: AHT20 init NG!\r\n");
            if (i++ == 10) {
                g_i2c_init = IOT_FAILURE;
                break;
            }
        }
    }
#endif

    // 接入WiFi网络
    rc = ConnectToHotspot(SSID, PSWD);
    printf("[main_task] MainTask: Connect to AP[%s] %s!\n\n", SSID, (rc == 0)?"OK":"NG");
    if (rc != 0) {
        return;
    }

    printf("[main_task] MainTask: MqttTaskInit:\n");
    MqttTaskInit();

    // 尝试连接MQTT服务器，最多重试3次
    for (i = 0; i < 3; i++) {
        printf("[main_task] MainTask: MqttTaskConnect: idx[%d]\r\n", i);
        rc = MqttTaskConnect(HOST_ADDR, HOST_PORT, MQTT_CLIENT_ID, MQTT_USERNAME, MQTT_PASSWORD);
        if (rc == 0) {
            break;
        } else {
            osDelay(100);
        }
    }
    printf("[main_task] MainTask: MqttTaskConnect: %s!\r\n", (rc == 0)?"OK":"NG");
    if (rc != 0) {
        return;
    }

    printf("[main_task] MainTask: MqttTaskSubscribe:\r\n");
    rc = MqttTaskSubscribe(SUBCRIB_TOPIC);
    printf("[main_task] MainTask: MqttTaskSubscribe: Subscribe Topic %s!\r\n", (rc == 0)?"OK":"NG");
    if (rc != 0) {
        return;
    }

    printf("[main_task] MainTask: MqttTaskPublish:\n");
    while (1) {
        osDelay(200);

    #if 1  // Publish Topic to HW Cloud
      #ifdef SUPPORT_AHT20
        if (g_i2c_init == IOT_SUCCESS) {
            // 启动测量
            if (AHT20_StartMeasure() != IOT_SUCCESS) {
                printf("[main_task] MainTask: AHT20_StartMeasure: NG!\r\n");
            }
            //获取测量结果
            if (AHT20_GetMeasureResult(&temp, &humi) != IOT_SUCCESS) {
                printf("[main_task] MainTask: AHT20_GetMeasureResult: NG!\r\n");
            }
        } else
      #endif
        {
            i = (i+1)%20;
            temp = 10.12345f + i;
            humi = 40.56789f + i;
        }

        sprintf(payload,
            "{\"services\":[{\"service_id\":\"%s\",\"properties\":{\"Temp\":%f,\"Humi\":%f}}]}",
            SERVICE_NAME, temp, humi);

        printf("[main_task] MainTask: MqttTaskPublish: Publish Topic\r\n");
        rc = MqttTaskPublish(PUBLISH_TOPIC, payload);
        if (rc != 0) {
            continue;
        }
    #endif

        if (door) {
            osDelay(100);
            door = 0;
            IoTGpioSetOutputVal(DOOR_ON_OFF_CTRL_GPIO, 0);
        }
    }
}

static void MainTaskEntry(void)
{
    osThreadAttr_t attr;
    attr.name = "MainTask";
    attr.attr_bits = 0U;
    attr.cb_mem = NULL;
    attr.cb_size = 0U;
    attr.stack_mem = NULL;
    attr.stack_size = 1024 * 10;
    attr.priority = osPriorityNormal;

    if (osThreadNew(MainTask, NULL, &attr) == NULL) {
        printf("[main_task] MainTaskEntry: Create MainTask: NG!\n");
    } else {
        printf("[main_task] MainTaskEntry: Create MainTask: OK!\n");
    }
}
APP_FEATURE_INIT(MainTaskEntry);